<?php

namespace App\Http\Controllers\Frontend\V10\Risk;

use App\Constants\RedisKey;
use App\Events\AuthStepEvent;
use App\Exceptions\GeneralException;
use App\Facades\CommonPlatformRequestFacade;
use App\Facades\RiskPlatformRequestFacade;
use App\Http\Controllers\Controller;
use App\Http\Requests\Frontend\V10\Risk\RiskRequest;
use App\Models\UserApplyRiskLog;
use App\Models\UserAuthSpiderTransLog;
use App\Models\UserAuthStepEventLog;
use App\Models\UserBankCard;
use App\Models\UserDeviceInfo;
use App\Models\UserInfo;
use App\Models\UserLoanRequest;
use Carbon\Carbon;
use Illuminate\Support\Facades\Redis;

class RiskController extends Controller {
    public function __construct() {
        $this->middleware('auth:api');
    }

    /**
     * @param RiskRequest $request
     * @author luwei
     * @date 2019-02-27 15:14
     * @return
     */
    public function spiderStatus(RiskRequest $request) {
        $userId     = \Auth::id();
        $carrierKey = sprintf(RedisKey::SPIDER_CARRIER_DATA, $userId);
        $zhimaKey   = sprintf(RedisKey::SPIDER_ZHIMA_DATA, $userId);

        $carrierData = Redis::get($carrierKey);
        $carrierData = $carrierData ? json_decode($carrierData, true) : null;
        $zhimaData   = Redis::get($zhimaKey);
        $zhimaData   = $zhimaData ? json_decode($zhimaData, true) : null;

        $cLoan = false;
        if ($carrierData && $carrierData['trade_no']) {
            //如果有授信数据且没有运营商数据  直接录入缓存中运营商爬虫记录
            $cLoan = UserLoanRequest::where('user_id', $userId)->where('current', 1)->where('user_phone_service_id', 0)->first();
            if ($cLoan) {
                $spider = UserAuthSpiderTransLog::byLoanRequestId($cLoan->id)->where('type',UserAuthSpiderTransLog::TYPE_CARRIER_ENG)->first();
                if ($spider) {
                    $spider->trade_no = $carrierData['trade_no'];
                    $spider->update();
                } else {
                    UserAuthSpiderTransLog::create([
                        'user_id'         => $userId,
                        'loan_request_id' => $cLoan->id,
                        'trade_no'        => $carrierData['trade_no'],
                        'type'            => UserAuthSpiderTransLog::TYPE_CARRIER_ENG
                    ]);
                }
            }

        }
        $zLoan = false;
        if ($zhimaData && $zhimaData['trade_no']) {
            //如果有授信数据且没有芝麻信用信息  直接录入缓存中芝麻分爬虫记录
            $zLoan = UserLoanRequest::where('user_id', $userId)->where('current', 1)->where('zhima_id', 0)->first();
            if ($zLoan) {
                $spider = UserAuthSpiderTransLog::byLoanRequestId($zLoan->id)->where('type',UserAuthSpiderTransLog::TYPE_ALIPAY_ENG)->first();
                if ($spider) {
                    $spider->trade_no = $zhimaData['trade_no'];
                    $spider->update();
                } else {
                    UserAuthSpiderTransLog::create([
                        'user_id'         => $userId,
                        'loan_request_id' => $zLoan->id,
                        'trade_no'        => $zhimaData['trade_no'],
                        'type'            => UserAuthSpiderTransLog::TYPE_ALIPAY_ENG
                    ]);
                }
            }
        }
        $data = [
            'phone_data' => $carrierData,
            'zhima_data' => $zhimaData
        ];
        return success($data);
    }


    /**
     * 开启新流爬虫接口，返回交易流水号
     * @param RiskRequest $request
     * @author luwei
     * @date 2019-01-04 20:45
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getSerialNum(RiskRequest $request) {
        $user     = \Auth::user();
        $userCert = $user->validCert->first();
        if (!$userCert) {
            throw new GeneralException('请先认证身份证');
        }
        $params = $this->extractInputFromRules($request, $request->rules());

        $data = [
            'name'   => $userCert->name,
            'certNo' => $userCert->num,
            'mobile' => $user->phone_num,
            'prodId' => UserLoanRequest::$TYPE[$params['type']]
        ];
        \DB::beginTransaction();
        try {
            //查询当前用户申请记录
            $loan = UserLoanRequest::byStatus(UserLoanRequest::STATUS_UN_APPLY)
                ->byUid($user->id)
                ->where('current', 1)
                ->first();
            \Log::debug('授信申请记录:' . json_encode($loan, JSON_UNESCAPED_UNICODE));
            if (!$loan) {
                throw new GeneralException('异常数据');
            }

            switch ($params['type']) {
                case UserLoanRequest::TYPE_CARRIER:
                    $type = UserAuthSpiderTransLog::TYPE_CARRIER_ENG;
                    break;
                case UserLoanRequest::TYPE_TAOBAO:
                    $type = UserAuthSpiderTransLog::TYPE_ALIPAY_ENG;
                    break;
                default:
                    throw new GeneralException('类型错误');
            }
            $flag = UserAuthSpiderTransLog::byLoanRequestId($loan->id)->where('type', $type)->first();
            //如果已经存在该类型爬虫记录  直接返回该爬虫id
            if ($flag) {
                $tradeNo = $flag->trade_no;
            } else {
                //获取交易流水号
                $ret = RiskPlatformRequestFacade::getSerialNum($data);
                //记录或更新爬虫返回流水号
                $tradeNo  = $ret['data']['tradeNo'];
                $par      = [
                    'loan_request_id' => $loan->id,
                    'trade_no'        => $tradeNo,
                    'type'            => $type,
                    'user_id'         => $user->id,
                ];
                UserAuthSpiderTransLog::create($par);
            }
            $return = [
                'name'    => $userCert->name,
                'card'    => $userCert->num,
                'phone'   => $user->phone_num,
                'user_id' => $tradeNo
            ];
            \Log::debug('获取爬虫流水号,'.json_encode($return,JSON_UNESCAPED_UNICODE));
            \DB::commit();
            return success($return);
        } catch (\Exception $e) {
            \DB::rollBack();
            throw new GeneralException($e->getMessage());
        }
    }

    /**
     * 风控查询结果
     * @param RiskRequest $request
     * @return mixed
     * @throws \App\Exceptions\GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @author luwei
     * @date 2019-01-05 20:48
     */
    public function queryRiskResult(RiskRequest $request) {
        $params = $this->extractInputFromRules($request, $request->rules());
        $flag   = UserApplyRiskLog::byRiskId($params['risk_id'])->count();
        if (!$flag) {
            return failed('风控查询ID不存在');
        }
        $ret = RiskPlatformRequestFacade::queryRiskResult($params);
        return success($ret['data']);
    }

    /**
     * 生成风控授信号
     * @param $num
     * @return string
     * @author luwei
     * @date 2019-01-05 20:48
     */
    private function creditNo($num) {
        if (is_numeric($num)) {
            $string = UserLoanRequest::CREDIT_NO_PREFIX . $num;
            return $string;
        }
    }

    /**
     * 构造风控发送数据
     * @param $loan
     * @param $user
     * @param $params
     * @return array
     * @author luwei
     * @date 2019-01-05 20:48
     */
    private function createParams($loan, $user, $params) {
        //银行卡关联信息
        if ($loan->bankCard) {
            $bankCardNum = $loan->bankCard->card_num;
        } else {
            throw new GeneralException('请先绑定银行卡信息');
        }

        //流水号
        $tradeNums = $loan->userTransLog;
        $tradeInfo = [];
        foreach ($tradeNums as $t) {
            $tradeInfo[] = $t->riskId;
        }

        //直系联系人
        if ($loan->baseInfo) {
            $userInfo = $loan->baseInfo;
        } else {
            throw new GeneralException('请先填写基本信息');
        }
        $directInfo = [
            [
                'name'         => $userInfo->linkman_first,
                'phone'        => $userInfo->linkman_first_phone,
                'relationShip' => $userInfo->linkman_first_relation,
                'remark'       => UserInfo::$USER_RELATION[$userInfo->linkman_first_relation]
            ]
        ];
        //一般联系人
        $generateInfo = [
            [
                'name'         => $userInfo->linkman_second,
                'phone'        => $userInfo->linkman_second_phone,
                'relationShip' => $userInfo->linkman_second_relation,
                'remark'       => UserInfo::$USER_RELATION[$userInfo->linkman_second_relation]
            ]
        ];
        $phoneInfo    = array_merge($generateInfo, $directInfo);
        //通讯录
        $phoneList    = $userInfo->phone_list ?? [];
        $retPhoneList = [];
        foreach ($phoneList as $data) {
            $retPhoneList[] = [
                'phone'  => $data['phone'],
                'name'   => $data['contactName'],
                'remark' => ''
            ];
        }

        //身份证相关信息
        if ($loan->userCert) {
            $cert = [
                "blackBox"               => $loan->userCert->issuing_authority,
                "certificateExpriy"      => $loan->userCert->valid_date_end,
                "certificateInAuthority" => $loan->userCert->issuing_authority,
                "idNo"                   => $loan->userCert->num,
                "userName"               => $loan->userCert->name,
                "homeAddress"            => $loan->userCert->domicile_address
            ];
        } else {
            throw new GeneralException('请认证身份证');
        }

        $data = [
            'bankCardNo'          => $bankCardNum,
            "companyName"         => optional($loan->baseInfo)->company,
            "creditApplyTime"     => Carbon::parse($loan->apply_time)->format('YmdHis'),
            "creditNo"            => $this->creditNo($loan->trans_id),
            "deviceId"            => (string)$params['device_id'],
            "deviceType"          => UserLoanRequest::$DEVICE_TYPE[$params['device_type']],
            "educationBackground" => $userInfo->edu_str,
            "faceParam"           => "",
            "flowFlag"            => (string)UserInfo::FLOW_FLAG_FULL,
            'emergencyContact'    => $phoneInfo,
            "phone"               => $user->phone_num,
            'phoneAddress'        => $retPhoneList,
            "tradeNOs"            => $tradeInfo,
        ];
        $data = array_merge($data, $cert);
        return $data;
    }

}
